package com.athuahua.spzx.service.impl;

import cn.hutool.core.date.DateTime;
import com.athuahua.spzx.dto.h5.OrderInfoDto;
import com.athuahua.spzx.entity.*;
import com.athuahua.spzx.exception.CodeException;
import com.athuahua.spzx.feignapi.CartFeignClient;
import com.athuahua.spzx.feignapi.ProductFeignClient;
import com.athuahua.spzx.feignapi.UserFeignClient;
import com.athuahua.spzx.mapper.OrderItemMapper;
import com.athuahua.spzx.mapper.OrderLogMapper;
import com.athuahua.spzx.utils.BaseContext;
import com.athuahua.spzx.utils.Result;
import com.athuahua.spzx.utils.ResultCodeEnum;
import com.athuahua.spzx.vo.CartInfoVo;
import com.athuahua.spzx.vo.h5.TradeVo;
import com.athuahua.spzx.vo.h5.UserInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.athuahua.spzx.service.OrderInfoService;
import com.athuahua.spzx.mapper.OrderInfoMapper;
import io.jsonwebtoken.lang.Collections;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author huahua
 * @description 针对表【order_info(订单)】的数据库操作Service实现
 * @createDate 2024-08-19 14:16:14
 */
@Service
@Slf4j
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo>
        implements OrderInfoService {

    @Resource
    private CartFeignClient cartFeignClient;
    @Resource
    private ProductFeignClient productFeignClient;

    @Resource
    private UserFeignClient userFeignClient;
    @Resource
    private OrderInfoMapper orderInfoMapper;
    @Resource
    private OrderItemMapper orderItemMapper;
    @Resource
    private OrderLogMapper orderLogMapper;


    @Override
    public TradeVo getTradeInfo() {

        List<OrderItem> orderItems = getOrderItems();

        BigDecimal totalPrice = new BigDecimal(0);
        for (OrderItem orderItem : orderItems) {
            totalPrice = totalPrice.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }


        TradeVo tradeVo = new TradeVo();
        tradeVo.setOrderItemList(orderItems);

        tradeVo.setTotalAmount(totalPrice);

        return tradeVo;
    }

    @Override
    @Transactional
    public Long submitOrder(OrderInfoDto orderInfoDto) {
        //1.购物车为空时抛出异常
        if (Collections.isEmpty(orderInfoDto.getOrderItemList())) {
            throw new CodeException(ResultCodeEnum.DATA_ERROR);
        }
        //2.库存量不足抛出异常
        for (OrderItem orderItem : orderInfoDto.getOrderItemList()) {
            ProductSku bySkuId = productFeignClient.getBySkuId(orderItem.getSkuId());
            if (bySkuId == null) {
                throw new CodeException(ResultCodeEnum.DATA_ERROR);
            }
            //检验库存
            if (orderItem.getSkuNum() > bySkuId.getStockNum()) {
                throw new CodeException(ResultCodeEnum.STOCK_LESS);
            }
        }
        //3. 添加数据到order_info表中 openFeign 调用用户收货地址信息
        OrderInfo orderInfo = new OrderInfo();
        Long currentId = BaseContext.getCurrentId();
        //3.1 调用openFeign 获取用户数据
        UserInfoVo userInfoVo = null;
        Result<UserInfoVo> currentUserInfo = userFeignClient.getCurrentUserInfo();
        if (currentUserInfo.getCode() == 200) {
            userInfoVo = currentUserInfo.getData();
        } else {
            throw new CodeException(ResultCodeEnum.DATA_ERROR);
        }

        orderInfo.setUserId(currentId);
        orderInfo.setOrderNo(String.valueOf(currentId) + "-" + System.currentTimeMillis());
        orderInfo.setNickName(userInfoVo.getNickName());
        //3.2 调用openFeign 获取收货地址信息
        UserAddress userAddress = userFeignClient.getUserAddress(orderInfoDto.getUserAddressId());
        if (userAddress == null) {
            throw new CodeException(ResultCodeEnum.DATA_ERROR);
        }
        orderInfo.setReceiverName(userAddress.getName());
        orderInfo.setReceiverPhone(userAddress.getPhone());
        orderInfo.setReceiverTagName(userAddress.getTagName());
        orderInfo.setReceiverProvince(Long.valueOf(userAddress.getProvinceCode()));
        orderInfo.setReceiverCity(Long.valueOf(userAddress.getCityCode()));
        orderInfo.setReceiverDistrict(Long.valueOf(userAddress.getDistrictCode()));
        orderInfo.setReceiverAddress(userAddress.getAddress());
        //订单金额
        BigDecimal totalPrice = new BigDecimal(0);
        for (OrderItem orderItem : orderInfoDto.getOrderItemList()) {
            totalPrice = totalPrice.add(orderItem.getSkuPrice().multiply(new BigDecimal(orderItem.getSkuNum())));
        }
        orderInfo.setTotalAmount(totalPrice);
        orderInfo.setCouponAmount(new BigDecimal(0));
        orderInfo.setOriginalTotalAmount(totalPrice);
        orderInfo.setFeightFee(orderInfoDto.getFeightFee());
        orderInfo.setPayType(2);
        orderInfo.setOrderStatus(0);

        orderInfoMapper.insert(orderInfo);


        //4.添加数据到order_item表中
        for (OrderItem orderItem : orderInfoDto.getOrderItemList()) {
            orderItem.setOrderId(orderInfo.getId());
            orderItemMapper.insert(orderItem);
        }

        //5.添加数据到order_log表中
        OrderLog orderLog = new OrderLog();
        orderLog.setOrderId(orderInfo.getId());
        orderLog.setProcessStatus(0);
        orderLog.setNote("订单提交");
        orderLogMapper.insert(orderLog);

        //6.清空购物车 openFeign 清空选中商品的购物车信息
        cartFeignClient.deleteCheck();


        //7.返回订单的id
        return orderInfo.getId();
    }

    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        return orderInfoMapper.selectById(orderId);
    }

    @Override
    public TradeVo buy(Long skuId) {
        //封装订单项的集合
        List<OrderItem> orderItems = new ArrayList<>();
        ProductSku bySkuId = productFeignClient.getBySkuId(skuId);
        OrderItem orderItem = new OrderItem();
        orderItem.setSkuId(skuId);
        orderItem.setSkuName(bySkuId.getSkuName());
        orderItem.setSkuNum(1);
        orderItem.setSkuPrice(bySkuId.getSalePrice());
        orderItem.setThumbImg(bySkuId.getThumbImg());
        orderItems.add(orderItem);


        TradeVo result = new TradeVo();
        result.setOrderItemList(orderItems);
        result.setTotalAmount(bySkuId.getSalePrice());

        return result;
    }

    @Override
    public IPage<OrderInfo> getAllOrderInfo(Integer page, Integer limit, Integer status) {
        IPage<OrderInfo> iPage = new Page<>(
                page,
                limit
        );
        //查询订单信息
        IPage<OrderInfo> orderInfoIPage = orderInfoMapper.selectPage(iPage, new LambdaQueryWrapper<OrderInfo>()
                .eq(OrderInfo::getUserId, BaseContext.getCurrentId())
                .eq(status != null , OrderInfo::getOrderStatus, status)
                .orderByDesc(OrderInfo::getUpdateTime));

        orderInfoIPage.getRecords().forEach(orderInfo -> {
            //根据订单id查询订单项
            List<OrderItem> orderItems = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                    .eq(OrderItem::getOrderId, orderInfo.getId()));
            orderInfo.setOrderItemList(orderItems);
        });
        return orderInfoIPage;
    }

    @Override
    public OrderInfo getOrderInfoByOrderNo(String orderNo) {
        OrderInfo orderInfo = orderInfoMapper.selectOne(
                new LambdaQueryWrapper<OrderInfo>()
                        .eq(OrderInfo::getOrderNo, orderNo)
        );
        List<OrderItem> orderItems = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .eq(OrderItem::getOrderId, orderInfo.getId())
                .orderByDesc(OrderItem::getUpdateTime));
        orderInfo.setOrderItemList(orderItems);


        return orderInfo;
    }

    @Override
    public void updateOrderStatus(String orderNo, Integer orderStatus) {
        OrderInfo orderInfo = orderInfoMapper.selectOne(
                new LambdaQueryWrapper<OrderInfo>()
                        .eq(OrderInfo::getOrderNo, orderNo)
        );
        orderInfo.setOrderStatus(orderStatus);
        orderInfo.setUpdateTime(DateTime.now());
        orderInfo.setPaymentTime(DateTime.now());
        orderInfo.setPayType(2);

        orderInfoMapper.updateById(orderInfo);

    }

    @NotNull
    private List<OrderItem> getOrderItems() {
        List<CartInfoVo> allCkecked = cartFeignClient.getAllCkecked();

        List<OrderItem> orderItems = new ArrayList<>();
        for (CartInfoVo cartInfoVo : allCkecked) {
            OrderItem orderItem = new OrderItem();
            orderItem.setSkuId(cartInfoVo.getSkuId());
            orderItem.setSkuName(cartInfoVo.getSkuName());
            orderItem.setSkuPrice(cartInfoVo.getCartPrice());
            orderItem.setSkuNum(cartInfoVo.getSkuNum());
            orderItem.setThumbImg(cartInfoVo.getImgUrl());
            orderItems.add(orderItem);
        }
        return orderItems;
    }
}




